原始题目:剑指 Offer 66. 构建乘积数组 (opens new window)
解题思路:
这道题的难点除了不能使用除法外,还不能使用暴力法去解,会超时。因此最好还是能在计算 时,能复用 的计算结果。
的定义如上图所示,将表格分为上三角和下三角,分别计算两个三角形的,就可以得到 的乘积。
算法流程:
- 初始化:数组 ,其中 ;
- 计算 的下三角各元素的乘积, 从 到 递增。计算 时,要借助 减少运算次数,;
- 计算 B[i] 的上三角各元素的乘积, 从 到 递减。使用辅助变量 ,用来存储计算过的结果(好像第 步里的 的作用)。
- 返回 B。
代码:
public int[] constructArr(int[] a) {
if (a == null || a.length == 0) {
return new int[0];
}
int[] ans = new int[a.length];
ans[0] = 1;
for (int i = 1; i < ans.length; i++) {
ans[i] = ans[i - 1] * a[i - 1];
}
int tmp = 1;
for (int i = ans.length - 1; i >= 0; i--) {
ans[i] *= tmp;
tmp *= a[i];
}
return ans;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
复杂度分析
- 时间复杂度:其中 为数组的长度,两轮遍历,使用 时间。
- 空间复杂度:辅助变量占用 的复杂度。